﻿using System;
using System.Drawing;
using System.Windows.Forms;
using SoftwareConsulting.BI11.Studio.Core.Project;
using SoftwareConsulting.BI11.Studio.Core.Project.Metadata;
using SoftwareConsulting.BI11.Studio.Core.Project.Metadata.Extensions;
using SoftwareConsulting.BI11.Studio.InternalServices;
using SoftwareConsulting.BI11.Studio.UI.ProjectExplorer.Dimensions;
using SoftwareConsulting.BI11.Studio.UI.ProjectExplorer.Extensions;
using SoftwareConsulting.BI11.Studio.UI.ProjectExplorer.Indicators;
using SoftwareConsulting.BI11.Studio.UI.ProjectExplorer.ClassificationProblems;
using SoftwareConsulting.BI11.Studio.UI.Properties;
using SoftwareConsulting.BI11.Controls.Metadata;

namespace SoftwareConsulting.BI11.Studio.UI.ProjectExplorer
{
    /// <summary>
    /// Диалог создания нового объекта метаданных
    /// </summary>
    public partial class CreateObjectDialog : RestorableForm
    {               
        private IMetadataObjectDescriptor _createdObjectDescriptor;//описатель созданного объекта
        private MetadataObjectKind _kind;
        private int _subKind;
        private IMetadataObjectDescriptor _parentObject;
        private ProjectExplorerForm _projectExplorerForm;
        private int _startFormHeight;
        private bool _withHelp;

        /// <summary>
        /// Возвращает описатель созданного объекта
        /// </summary>
        public IMetadataObjectDescriptor CreatedObject
        {
            get
            {
                return _createdObjectDescriptor;
            }            
        }

        /// <summary>
        /// Возвращает текущий проект
        /// </summary>
        private ProjectDescriptor ProjectLink
        {
            get
            {
                return _projectExplorerForm.ProjectLink;
            }
        }

        /// <summary>
        /// Инициализация диалога
        /// </summary>
        private void Initialize()
        {
            _createdObjectDescriptor = null;
            string objtype = _kind.ToUserString();
            switch(_kind)
            {
                case MetadataObjectKind.Indicator:
                    objtype = ((IndicatorType)_subKind).ToUserString();
                    break;
                case MetadataObjectKind.Dimension:
                    objtype = ((DimensionKind)_subKind).ToUserString();
                    break;
                case MetadataObjectKind.Model:
                    objtype = ((ModelType)_subKind).ToUserString();
                    break;
                case MetadataObjectKind.ClassificationProblem:
                    objtype = ((ClassificationProblemKind)_subKind).ToUserString();
                    break;
            }
            Icon ic = _kind.GetIcon();
            Image im = _kind.GetImage(MetadataObjectImageSize.Large, MetadataObjectState.Normal);
            NameBox.Text = ProjectLink.RepositoryLink.ProposeNewObjectName(_kind);
            LabelBox.Text = ProjectLink.RepositoryLink.ProposeNewObjectLabel(_kind);
            Text = Resources.BI_PROJECTEXPLORER_CREATINGOBJECTCAPTION + " - " + objtype;
            Icon = ic;
            pictureBox1.Image = im;
            _startFormHeight = this.Height;
            tipBox1.TipText = _kind.GetObjectTip();
            _withHelp = _projectExplorerForm.SimpleMode;
            tipBox1.Closed = !_withHelp;
        }

        /// <summary>
        /// Отменяет создание объекта и закрывает диалог
        /// </summary>
        private void CancelAndClose()
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        /// <summary>
        /// Создание объекта и закрытие диалога
        /// </summary>
        private void ApplyAndClose()
        {
            string newname = NameBox.Text;
            string newLabel = LabelBox.Text;
            string newdescription = DescriptionBox.Text;                                    
            try
            {                                        
                switch (_kind)
                {
                    case MetadataObjectKind.Indicator:
                        IndicatorType indicatorType = IndicatorType.None;
                        if (_subKind == 0)
                        {
                            SetIndicatorTypeDialog sitd = new SetIndicatorTypeDialog();
                            if (sitd.ShowDialog() != DialogResult.OK)
                            {
                                CancelAndClose();
                                return;
                            }
                            indicatorType = sitd.Type;
                        }
                        else
                        {
                            indicatorType = (IndicatorType)_subKind;
                        }
                        _createdObjectDescriptor = ProjectLink.RepositoryLink.CreateObject(
                            indicatorType, 
                            IndicatorLimiterState.Indicator,
                            newname, 
                            newLabel, 
                            newdescription, 
                            _parentObject);
                        break;
                    case MetadataObjectKind.Dimension:
                        DimensionKind dimKind = DimensionKind.None;
                        if (_subKind == 0)
                        {
                            SetDimensionTypeDialog sdt = new SetDimensionTypeDialog();
                            if (sdt.ShowDialog() != DialogResult.OK)
                            {
                                CancelAndClose();
                                return;
                            }                            
                            dimKind = sdt.Kind;
                        }
                        else
                        {
                            dimKind = (DimensionKind)_subKind;
                        }
                        _createdObjectDescriptor = ProjectLink.RepositoryLink.CreateObject(
                            MetadataObjectKind.Dimension,
                            (int)dimKind,
                            newname, 
                            newLabel, 
                            newdescription, 
                            _parentObject);                        
                        break;
                    case MetadataObjectKind.Model:
                        _createdObjectDescriptor = ProjectLink.RepositoryLink.CreateObject(
                            MetadataObjectKind.Model,
                            _subKind,
                            newname, 
                            newLabel, 
                            newdescription, 
                            _parentObject);
                        break;
                    case MetadataObjectKind.ClassificationProblem:
                        ClassificationProblemKind cpKind = ClassificationProblemKind.None;
                        if (_subKind == 0)
                        {
                            SetClassificationProblemTypeDialog scpt = new SetClassificationProblemTypeDialog();
                            if (scpt.ShowDialog() != DialogResult.OK)
                            {
                                CancelAndClose();
                                return;
                            }                            
                            cpKind = scpt.Kind;
                        }
                        else
                        {
                            cpKind = (ClassificationProblemKind)_subKind;
                        }
                        _createdObjectDescriptor = ProjectLink.RepositoryLink.CreateObject(
                            MetadataObjectKind.ClassificationProblem,
                            (int)cpKind,
                            newname,
                            newLabel,
                            newdescription,
                            _parentObject);
                        break;
                    default:
                        _createdObjectDescriptor = ProjectLink.RepositoryLink.CreateObject(_kind, newname, newLabel, newdescription, _parentObject);
                        break;
                }
            }
            catch (BICalculationNoCalendarsException ex)
            {
                GeneralMethods.ShowUserError(ex.Message);
                return;
            }
            catch (BIIncorrectNameException ex)
            {
                NameBox.Focus();
                GeneralMethods.ShowUserError(ex.Message);
                return;
            }
            catch (BIMetadataObjectEmptyNameException ex)
            {
                NameBox.Focus();
                GeneralMethods.ShowUserError(ex.Message);
                return;
            }
            catch (BIMetadataObjectIncorrectLabelException ex)
            {
                LabelBox.Focus();
                GeneralMethods.ShowUserError(ex.Message);
                return;
            }
            DialogResult = DialogResult.OK;
            Close();
        }

        /// <summary>
        /// Конструктор формы
        /// </summary>
        /// <param name="projectExplorerForm"></param>
        /// <param name="subKind"></param>
        /// <param name="parentObject"></param>
        public CreateObjectDialog(ProjectExplorerForm projectExplorerForm, DimensionKind subKind, IMetadataObjectDescriptor parentObject)
            : this(projectExplorerForm, MetadataObjectKind.Dimension, (int)subKind, parentObject)
        {
        }

        /// <summary>
        /// Конструктор формы
        /// </summary>
        /// <param name="projectExplorerForm"></param>
        /// <param name="subKind"></param>
        /// <param name="parentObject"></param>
        public CreateObjectDialog(ProjectExplorerForm projectExplorerForm, ModelType subKind, IMetadataObjectDescriptor parentObject)
            : this(projectExplorerForm, MetadataObjectKind.Model, (int)subKind, parentObject)
        {
        }

        /// <summary>
        /// Конструктор формы
        /// </summary>
        /// <param name="projectExplorerForm"></param>
        /// <param name="subKind"></param>
        /// <param name="parentObject"></param>
        public CreateObjectDialog(ProjectExplorerForm projectExplorerForm, ClassificationProblemKind subKind, IMetadataObjectDescriptor parentObject)
            : this(projectExplorerForm, MetadataObjectKind.ClassificationProblem, (int)subKind, parentObject)
        {
        }

        /// <summary>
        /// Конструктор формы
        /// </summary>
        /// <param name="projectExplorerForm"></param>
        /// <param name="subKind"></param>
        /// <param name="parentObject"></param>
        public CreateObjectDialog(ProjectExplorerForm projectExplorerForm, IndicatorType subKind, IMetadataObjectDescriptor parentObject)
            : this(projectExplorerForm, MetadataObjectKind.Indicator, (int)subKind, parentObject)
        {
        }

        /// <summary>
        /// Конструктор формы
        /// </summary>
        /// <param name="projectExplorerForm"></param>
        /// <param name="kind"></param>
        /// <param name="parentObject"></param>
        public CreateObjectDialog(ProjectExplorerForm projectExplorerForm, MetadataObjectKind kind, IMetadataObjectDescriptor parentObject)
            : this(projectExplorerForm, kind, 0, parentObject)
        {
        }

        /// <summary>
        /// Конструктор формы
        /// </summary>
        /// <param name="projectExplorerForm"></param>
        /// <param name="objectKind"></param>
        /// <param name="parentObject"></param>
        public CreateObjectDialog(ProjectExplorerForm projectExplorerForm, MetadataObjectKind objectKind, int subKind, IMetadataObjectDescriptor parentObject)
        {         
            _kind = objectKind;
            _subKind = subKind;
            _parentObject = parentObject;
            _projectExplorerForm = projectExplorerForm;            
            InitializeComponent();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            CancelAndClose();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            ApplyAndClose();
        }

        private void CreateObjectDialog_Load(object sender, EventArgs e)
        {
            Initialize();
        }

        private void tipBox1_OnRolledUp()
        {
            _withHelp = false;
            Height = tipBox1.Top + tipBox1.Height + 62;
        }

        private void tipBox1_OnRolledDown()
        {
            _withHelp = true;
            Height = tipBox1.Top + tipBox1.Height + 62;
        }

        private void CreateObjectDialog_FormClosed(object sender, FormClosedEventArgs e)
        {
            _projectExplorerForm.SimpleMode = _withHelp;
        }
    }
}
